package com.cqust.wdm.emsboot.config.security;

/**
 * @version 1.0
 */

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfiguration {
    //1. 创建realm
    @Bean
    public CustomRealm getRealm() {

        CustomRealm customRealm = new CustomRealm();
        customRealm.setCredentialsMatcher(credentialsMatcher());
        return customRealm;
    }

    public HashedCredentialsMatcher credentialsMatcher() {

        HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();
        // 散列算法:这里使用SHA256算法;
        shaCredentialsMatcher.setHashAlgorithmName(SHA256Util.HASH_ALGORITHM_NAME);
        shaCredentialsMatcher.setHashIterations(SHA256Util.HASH_ITERATIONS);
        return shaCredentialsMatcher;
    }

    //2. 创建安全管理器
    @Bean
    public SecurityManager getSecurityManager(CustomRealm realm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(realm);

        return securityManager;
    }

    //3. 配置shiro过滤器

    /**
     * 在web程序中，shiro进行权限控制全部是通过一组过滤器集合进行控制
     * 通过map来对不同的地址进行过滤，通过value来决定用哪种方式来过滤
     *
     * @param securityManager
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        //1. 创建过滤器工厂
        ShiroFilterFactoryBean filterFactory = new ShiroFilterFactoryBean();
        //2. 设置安全管理器
        filterFactory.setSecurityManager(securityManager);
        //3. 通用配置（跳转登录页面，为授权跳转的页面）
        filterFactory.setLoginUrl("/autherror?code=1");//未登录跳转到url地址
        filterFactory.setUnauthorizedUrl("/autherror?code=2");//未授权
        //4. 设置过滤器集合

        /**
         * 设置所有的过滤器：有顺序map
         *      key = 拦截的url地址
         *      value = 过滤器类型
         */
        Map<String, String> filterMap = new LinkedHashMap<>();
//        filterMap.put("/user/home", "anon"); //当前请求地址可以匿名访问

        //具有某种权限才能访问
        //使用过滤器的形式配置权限过滤
//        filterMap.put("/user/home", "perms[user-home]");//如果不具备权限，会跳转到上面设置的未授权的地址

        //具有某种角色才能登录
//        filterMap.put("/user/home", "roles[系统管理员]");
        filterMap.put("/user/**" , "authc");  //当前请求地址必须认证之后可以访问

        filterFactory.setFilterChainDefinitionMap(filterMap);

        return filterFactory;
    }

    @Bean
    public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }

    //配置shiro注解支持
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }
}
